#!/usr/bin/env python
#-*- coding:utf-8 -*-

from path.path import PathPoint, Path
from common.node import Node

class Planner(object):
    def __init__(self, graph, start, goal):
        self.graph = graph
        self.start = start
        self.goal = goal
        self.result = None

    @property
    def graph(self):
        if hasattr(self, "_graph"):
            return self._graph
        return None

    @graph.setter
    def graph(self, graph):
        self._graph = graph

    @property
    def start(self):
        if hasattr(self, "_start"):
            return self._start
        return None

    @start.setter
    def start(self, start):
        self._start = start

    @property
    def goal(self):
        if hasattr(self, "_goal"):
            return self._goal
        return None

    @goal.setter
    def goal(self, goal):
        self._goal = goal

    @property
    def result(self):
        if hasattr(self, "_result"):
            return self._result
        return None

    @result.setter
    def result(self, result):
        self._result = result

    @property
    def path(self):
        print("path is \n{}".format(self.result))
        return self.result

    def check(self, graph=None, start=None, goal=None):
        if not graph is None:
            self.graph = graph
        if not start is None:
            self.start = start
            if isinstance(start, Node):
                self.start = start.nid
        if not goal is None:
            self.goal = goal
            if isinstance(goal, Node):
                self.goal = goal.nid
        if self.graph is None or self.start is None or self.goal is None:
            return False
        return True

    def reach_goal(self, nid):
        if nid == self.goal:
            return True
        return False

    def successor(self, nid):
        return self.graph.successor(nid)

    def cost(self, from_u, to_v):
        return self.graph.cost(from_u, to_v)

    def distance(self, from_u, to_v, mode='Euler'):
        return self.graph.distance(from_u, to_v, mode)

    def blocked(self, from_u, to_v=None):
        return self.graph.blocked(from_u, to_v)

    def heuristic(self, from_u, to_v):
        return self.graph.heuristic(from_u, to_v)

    def generate_path(self, nid):
        _came = []
        while nid is not None:
            _came.append(nid)
            nid = self.came_from[nid]
        _res = []
        for nid in _came[-1::-1]:
            point = PathPoint(nid, self.graph.position(nid))
            _res.append(point)
        self.result = Path(_res)
        return self.result

    def plan(self, graph=None, start=None, goal=None):
        print("plan in graph {} from {} to {}".format(graph, start, goal))
        raise Exception('unimplemented algorithm !')
   
if __name__ == "__main__":
    pass